package com.example.thread.d9CompletableFuture2.d4异步任务编排;

import com.example.thread.d9CompletableFuture2.CommonUtils;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * 当其中一个Future依赖于另一个Future，使用thenCompose()用于组合两个Future，如果两个
 * Future之间没有依赖关系，你希望两个Future独立运行并在两者都完成之后执行回调操作时，则使用
 * thenCombine（）
 * T是第一个任务的结果，U是第二个任务的结果，V是经BiFunction应用转换后的结果
 * CompletableFuture<V> thenCombine(CompletableFuture<U> other,BiFunction<T,U,V> func)
 */
public class d3_ThenCombineDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CommonUtils.printThreadLog("main start");

        // 读取敏感词
        CompletableFuture<String[]> future1 = CompletableFuture.supplyAsync(() -> {
            CommonUtils.printThreadLog("读取敏感词开始");
            String content = CommonUtils.readFile("tmd,nb");
            String[] strings = content.split(",");
            return strings;
        });

        // 读取news
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            CommonUtils.printThreadLog("读取敏感词");
            String file = CommonUtils.readFile("hello world,tmd");
            return file;
        });

        // 替换 第一个参数是future1的，
        CompletableFuture<String> future = future1.thenCombine(future2, (strings, file) -> {
            // 替换操作
            CommonUtils.printThreadLog("替换开始");
            for (String word : strings) {
                if (file.indexOf(word) > 0) {
                    file = file.replace(word, "***");
                }
            }
            return file;
        });
        String news = future.get();
        CommonUtils.printThreadLog("转换后结果:"+news);

        CommonUtils.printThreadLog("main continue");
        CommonUtils.printThreadLog("main end");
    }

    /**
     * 总结：
     * 当两个Future都完成时，才将两个异步任务的结果传递给thenCombine()的回调函数做进一步处理
     * 和以往一样，thenCombine也存在异步回调变体版本
     * CompletableFuture<V> thenCombine(CompletableFuture<U> other,BiFunction<T,U,V> func)
     * CompletableFuture<V> thenCombineAsync(CompletableFuture<U> other,BiFunction<T,U,V> func)
     * CompletableFuture<V> thenCombineAsync(CompletableFuture<U> other,BiFunction<T,U,V> func,Executor executor)
     */
}
